﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace M5.GeminiHybird.Core.XHR
{
    public class HttpServer
    {
        string Root = System.Environment.CurrentDirectory + "\\www";
        //string DefautPage = "index.html";
        public readonly string HTTP_DOMAIN = $"http://localhost:{Helper.AppSettingsReader<DTO.AppSettings_DTO>.AppSetting.HttpServerPort}/";

        public void Start()
        {

            HttpListener httpListener = new HttpListener();

            httpListener.AuthenticationSchemes = AuthenticationSchemes.Anonymous;
            httpListener.Prefixes.Add(HTTP_DOMAIN);
            httpListener.Stop();
            try
            {

                httpListener.Start();
            }
            catch (Exception e)
            {
                MessageBox.Show("端口被占用,请重新设置");
                Console.WriteLine(e.ToString());
                return;
            }




            new Thread(new ThreadStart(delegate
            {
                while (true)
                {
                    HttpListenerContext httpListenerContext = httpListener.GetContext();

                    httpListenerContext.Response.StatusCode = 200;



                    Execute(httpListenerContext);
                }
            })).Start();
        }

        private void Execute(HttpListenerContext httpListenerContext)
        {
            using (var writer = httpListenerContext.Response.OutputStream)
            {
                string rawUrl = httpListenerContext.Request.RawUrl;

                if (string.IsNullOrEmpty(Path.GetExtension(rawUrl)))
                {

                    httpListenerContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
                    httpListenerContext.Response.Headers.Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
                    httpListenerContext.Response.Headers.Add("Access-Control-Allow-Headers", "Origin, Content-Type, Accept");
                    httpListenerContext.Response.Headers.Add("Accept-Language", "zh-CN");
                    httpListenerContext.Response.Headers.Add("Accept", "POST, GET, OPTIONS");
                    httpListenerContext.Response.Headers.Add("Content-Type", "application/json; charset=UTF-8");

                    if (httpListenerContext.Request.HttpMethod.ToLower() == "options")
                    {
                        httpListenerContext.Response.OutputStream.Close();
                        return;
                    }

                    httpListenerContext.Response.ContentType = "application/json";

                    Controller.BaseController baseController = Routes.FindController(rawUrl);
                    if (baseController == null)
                    {
                        httpListenerContext.Response.StatusCode = 404;
                        byte[] bufferError = Encoding.UTF8.GetBytes($"没有找到{rawUrl}配置的处理程序");
                        writer.Write(bufferError, 0, bufferError.Length);
                        writer.Close();
                        return;
                    }

                    string routeData = Routes.RouteData(httpListenerContext.Request);
                    string result = baseController.Execute(routeData);

                    byte[] bufferResult = Encoding.UTF8.GetBytes(result);
                    Tool.BufferReader<byte> bufferReader = new Tool.BufferReader<byte>(bufferResult);
                    while (bufferReader.HasNext())
                    {
                        byte[] buffer = bufferReader.ReadRange(4096);
                        writer.Write(buffer, 0, buffer.Length);
                    }
                    writer.Close();
                    return;
                }



                string FilePath = Root + rawUrl;
                if (!File.Exists(FilePath))
                {
                    httpListenerContext.Response.StatusCode = 404;
                    byte[] bufferError = Encoding.UTF8.GetBytes($"没有找到与{rawUrl}相关的静态文件");
                    writer.Write(bufferError, 0, bufferError.Length);
                    writer.Close();
                    return;
                }


                FileStream stream = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
                byte[] buff = new byte[4096];

                int count = 0;
                while ((count = stream.Read(buff, 0, buff.Length)) != 0)
                {
                    writer.Write(buff, 0, count);
                }

                writer.Close();
                stream.Close();

            }
        }
    }
}
